package com.hfi.plugin;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Statement;
import java.util.Properties;

/**
 * @author ChangLiang
 * @date 2019/5/24
 */
@Intercepts({@Signature(type = StatementHandler.class,method = "parameterize",args = Statement.class)})
public class MyFirstPlugin implements Interceptor {
    /**
     * 动态代理对象的拦截器 写拦截的业务逻辑
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());

        Object target = invocation.getTarget();
        System.out.println("当前拦截到的对象："+target);

        // 目标：动态的改变一下sql运行的参数：
        // 无论查询http://127.0.0.1:8089/mybatis-spring-demo/getEmployeeById?id=2 id为多少
        // 实际从数据库查询3号员工

        // 拿到target的元数据
        MetaObject metaObject = SystemMetaObject.forObject(target);
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("sql语句用的参数是："+value);

        //修改完sql语句要用的参数
        metaObject.setValue("parameterHandler.parameterObject", 3);

        // 放行 执行目标方法
        Object proceed = invocation.proceed();
        return proceed;
    }

    /**
     * 包装目标对象
     * 包装：为目标对象创建一个代理对象
     * @param o
     * @return
     */
    @Override
    public Object plugin(Object o) {

        System.out.println("MyFirstPlugin...plugin:mybatis将要包装的对象"+o);

        // 我们可以借助Plugin的wrap方法来使用当前Interceptor包装我们的目标对象
        Object wrap = Plugin.wrap(o, this);
        return wrap;
    }

    /**
     * 将插件注册时的property属性设置进来
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {
        System.out.println("插件配置的信息："+properties);
    }
}
